package com.mason.forum.controller;

import com.mason.forum.common.APPResult;
import com.mason.forum.common.ResultCode;
import com.mason.forum.model.User;
import com.mason.forum.service.IUserService;
import com.mason.forum.utils.SessionUtils;
import com.mason.forum.utils.StringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 马拉圈
 * Date: 2023-10-05
 * Time: 19:36
 */
@Api(tags = "用户相关接口") //对controller的描述
@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {

    @Resource
    private IUserService userService;


    /**
     * 普通用户注册接口
     * @param username 用户名
     * @param nickname 昵称
     * @param password 密码
     * @param passwordRepeat 确认密码
     * @return
     */
    @ApiOperation("用户注册")
    @PostMapping("/register")  //注解完成非空校验，但是只是区分null与非null罢了，主要的非空校验还是在service里，如果为null就会抛异常，然后被
    public APPResult register(@ApiParam("用户名") @RequestParam("username") @NonNull String username,
                              @ApiParam("昵称") @RequestParam("nickname") @NonNull String nickname,
                              @ApiParam("密码") @RequestParam("password") @NonNull String password,
                              @ApiParam("确认密码") @RequestParam("passwordRepeat") @NonNull String passwordRepeat) {

//        传统的方式：
//        if(!StringUtils.hasLength(username, nickname, password, passwordRepeat)) {
//            // 直接返回错误信息
//            return APPResult.failed(ResultCode.FAILED_PARAMS_VALIDATE);
//        }
        // 1. 校验密码与确认密码是否相同
        if(!password.equals(passwordRepeat)) {
            log.warn(ResultCode.FAILED_TWO_PWD_NOT_SAME.toString());
            return APPResult.failed(ResultCode.FAILED_TWO_PWD_NOT_SAME);
        }
        // 2. 构造一个对象
        User user = new User();
        user.setUsername(username);
        user.setPassword(password);
        user.setNickname(nickname);
        // 3. 调用service方法
        userService.createNormalUser(user);
        // 4. 返回成功
        return APPResult.success();
    }

    /**
     * 登录验证
     * @param username 用户名
     * @param password 密码
     * @return
     */
    @ApiOperation("用户登录")
    @PostMapping("/login")
    public APPResult login(HttpServletRequest request,
                           @ApiParam("用户名") @RequestParam("username") @NonNull String username,
                           @ApiParam("密码") @RequestParam("password") @NonNull String password) {
        // 1. 调用service的登录验证逻辑
        User user = userService.login(username, password);
        // 2. 如果user非空，设置到session里，同时框架帮我们返回setCookie
        if(user != null) {
            SessionUtils.setUser(request, user);
            return APPResult.success();
        }else {
            log.warn(ResultCode.FAILED_LOGIN.toString());
            return APPResult.failed(ResultCode.FAILED_LOGIN);
        }
    }

    /**
     * 获取用户信息
     * @param request 请求
     * @param id 用户id（非必传）
     * @return 返回用户信息
     */
    @ApiOperation("获取用户信息")
    @RequestMapping(value = "/info", method = {RequestMethod.GET, RequestMethod.POST})
    public APPResult<User> getUserInfo(HttpServletRequest request,
                                       @ApiParam("用户ID") @RequestParam(value = "id", required = false) Long id) {
        User user = null;// 返回的user对象
        if(id == null) {
            // 1. 如果id为null，从session中获取
            user = SessionUtils.getUser(request);
            if(user == null) {
                log.warn(ResultCode.FAILED_FORBIDDEN.toString());
                return APPResult.failed(ResultCode.FAILED_FORBIDDEN);//无权访问
            }
            // 此方法也为获取当前登录用户的详情，所以在session里面的信息是旧的，所以要更加用户id再查一次~
            id = user.getId();
        }
        // 2. 从数据库中获取
        user = userService.selectById(id);
        if(user == null) {
            log.warn(ResultCode.FAILED_USER_NOT_EXISTS.toString());
            return APPResult.failed(ResultCode.FAILED_USER_NOT_EXISTS);//找不到
        }
        return APPResult.success(user);
    }

    @ApiOperation("退出登录")
    @GetMapping("/logout")
    public APPResult logout(HttpServletRequest request) {
        SessionUtils.remove(request);
        log.info("退出成功");
        return APPResult.success("退出成功！");
    }

    @ApiOperation("更新用户信息")
    @PostMapping("/update")//返回一个更新后的数据
    public APPResult<User> updateUserInfo(HttpServletRequest request,
//                                    @SessionAttribute(APPConfig.USER_SESSION_KEY) User user,//导致api测试界面不好看
                                    @ApiParam("用户名") @RequestParam(value = "username", required = false) String username,
                                    @ApiParam("昵称") @RequestParam(value = "nickname", required = false) String nickname,
                                    @ApiParam("性别") @RequestParam(value = "gender", required = false) Byte gender,
                                    @ApiParam("邮箱") @RequestParam(value = "email", required = false) String email,
                                    @ApiParam("手机号") @RequestParam(value = "phoneNum", required = false) String phoneNum,
                                    @ApiParam("简介") @RequestParam(value = "remark", required = false) String remark) {
        // 参数校验
        if(StringUtils.hasNotLength(username, nickname, email, phoneNum, remark) && gender == null) {
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            return APPResult.failed(ResultCode.FAILED_PARAMS_VALIDATE);
        }
        // 获取当前登录用户信息
        User user = SessionUtils.getUser(request);
        // 构造初步修改对象
        User updateUser = new User();
        updateUser.setId(user.getId());
        updateUser.setGender(gender);
        updateUser.setPhoneNum(phoneNum);
        updateUser.setEmail(email);
        updateUser.setNickname(nickname);
        updateUser.setUsername(username);
        updateUser .setRemark(remark);
        // service层 - 修改
        userService.updateUserInfo(updateUser);
        // service - 查询
        user = userService.selectById(user.getId());
        // 成功返回
        return APPResult.success(user);
    }

    @ApiOperation("修改用户密码")
    @PostMapping("/password")
    public APPResult updateUserInfo(HttpServletRequest request,
                                    @ApiParam("老密码") @RequestParam("oldPassword") @NonNull String oldPassword,
                                    @ApiParam("密码") @RequestParam("newPassword") @NonNull String password,
                                    @ApiParam("确认密码") @RequestParam("passwordRepeat") @NonNull String passwordRepeat) {
        //  校验密码与确认密码是否相同
        if(!password.equals(passwordRepeat)) {
            log.warn(ResultCode.FAILED_TWO_PWD_NOT_SAME.toString());
            return APPResult.failed(ResultCode.FAILED_TWO_PWD_NOT_SAME);
        }
        User user = SessionUtils.getUser(request);
        if(user.getState() == 1 || user.getDeleteState() == 1) {
            log.warn(ResultCode.FAILED_USER_BANNED.toString());
            return APPResult.failed(ResultCode.FAILED_USER_BANNED);
        }
        // service - 修改密码
        userService.modifyUserPassword(user.getId(), password, oldPassword);
        // 修改密码后登录状态取消
        SessionUtils.remove(request);
        // 成功返回
        return APPResult.success();
    }


}
